import socket
import threading
import time

data = "你好"
port_1 = 12345


def send_broadcast(message, port):
    # 创建UDP套接字（在循环内保持打开，避免频繁创建/关闭）
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)  # 允许广播
    try:
        # 发送消息（只发一次也可以，保持socket打开）
        s.sendto(message.encode('utf-8'), ('10.70.255.255', port))
        print("[发送成功] 广播消息已发送")
        # 延迟关闭，确保发送操作完成
        time.sleep(1)
    except Exception as e:
        print(f"[发送失败] {e}")
    finally:
        s.close()  # 确保socket最终关闭


def listen_broadcast(port=12345):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 允许端口复用
    s.bind(('', port))  # 监听所有IP的指定端口
    print(f"[监听中] 正在监听 UDP 广播端口 {port} ...")

    while True:
        try:
            data, addr = s.recvfrom(1024)
            print(f"[收到消息] 来自 {addr}: {data.decode('utf-8')}")
        except Exception as e:
            print(f"[接收失败] {e}")
            break


# 关键修复：先启动监听线程，再发送消息
if __name__ == "__main__":
    # 1. 先启动监听线程（确保接收方就绪）
    listen_thread = threading.Thread(target=listen_broadcast, args=(port_1,), daemon=True)
    listen_thread.start()
    # 延迟1秒，确保监听已启动
    time.sleep(1)

    # 2. 再发送广播消息
    send_broadcast(data, port_1)

    # 3. 保持主线程运行（否则程序会立即退出）
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("程序已退出")
